home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’89 / gadlife / source (ugly) / patch.file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-05-08  |  4.8 KB  |  146 lines  |  [TEXT/KAHL]

  1. #include "main.h"
  2.  
  3. #define    asyncTrapBit    0x400
  4.  
  5. /**************************************************************
  6. *                                                                        *
  7. *    The following are the 'oldFileTraps' that are patched, or not, according to the contents    *
  8. *    of the whichTraps arrays.  Traps that are already patched *are* patched, but are        *
  9. *    treated differently.  The replacement routine replaces the trap dispatcher's return addr    *
  10. *    on the stack with its own, so that it will regain control without disrupting whatever        *
  11. *    stack peeking Apple's patches are doing.  This makes it 'safe' to do tail patches.            *
  12. *                                                                        *
  13. *    Generally speaking, those that could take an appreciable amount of time are patched,        *
  14. *    while those that don't usually are not.  At the very least, status, control, getvol, and    *
  15. *    setvol must not be patched, as some DAs and multifinder repeatedly call these.            *
  16. *    Also, mountvol, unmountvol, and initqueue cannot be called asyncronously.            *
  17. *                                                                        *
  18. *        0 = open        1 = close        2 = read        3 = write        4 = control        *
  19. *        5 = status        6 = killio        7 = getvolinfo    8 = create        9 = delete            *
  20. *        a = openrf        b = rename    c = getfileinfo    d = setfileinfo    e = unmountvol        *
  21. *        f = mountvol    10 = allocate    11 = geteof    12 = seteof    13 = flushvol        *
  22. *        14 = getvol    15 = setvol    16 = initqueue    17 = eject        18 = getfpos        *
  23. *                                                                        *
  24. *        41 = setfillock    42 = rstfillock    43 = setfiltype    44 = setfpos    45 = flushfile        *
  25. *                                                                        *
  26. **************************************************************/
  27.  
  28. #define    trapCount        0x46
  29.  
  30. long        oldFileTraps[ trapCount ];
  31. int        whichTraps[ trapCount ] = 
  32.             {    1,1,1,1,0,    0,0,1,1,1,    1,1,1,1,0,    0,1,0,1,1,
  33.                 0,0,0,1,0,    0,0,0,0,0,    0,0,0,0,0,    0,0,0,0,0,
  34.                 0,0,0,0,0,    0,0,0,0,0,    0,0,0,0,0,     0,0,0,0,0,
  35.                 0,0,0,0,0,    1,1,1,1,1        };
  36.  
  37. /**************************************************************
  38. *                                                                        *
  39. *                                                                        *
  40. **************************************************************/
  41.  
  42. doFileBackground() {
  43.     doBackground( lotsElseToDo, noGray, NULL );
  44. }
  45.  
  46. /**************************************************************
  47. *                                                                        *
  48. *    trap dispatcher calls the OS routines with d1, d2, ?a0?, a1, and a2 saved, and with        *
  49. *    d1 holding the original trap word, d2 holding the trap table offset, and a2 holding the        *
  50. *    address of the trap.  Bit 10 of d1 tells us whether the trap was async or not.            *
  51. *                                                                        *
  52. **************************************************************/
  53.  
  54. int            trapWord;        /* the original trap word, gotten for us by the trap dispatcher.            */
  55. ParmBlkPtr    parms;
  56. long            completion,     /* the old completion routine value for sync calls converted            */
  57.             dispatcher;    /* the dispatcher return address, so I can get away with tail patching    */
  58.  
  59.  
  60. long        theMem[0x400],    /* trapWord, parms, completion, dispatcher        */
  61.         *storage = theMem;
  62.  
  63. #define    trapWord        0
  64. #define    parms        4
  65. #define    completion    8
  66. #define    dispatcher        12
  67. #define    storageCount    16
  68.  
  69. doFileTrap()
  70.     {
  71.     int        fake;        /* forces link - otherwise it's not for sure    */
  72.     asm    {
  73.         unlk        a6
  74.         move.l    a5,-(sp)
  75.         move.l    CurrentA5,a5
  76.         add.l        #storageCount,storage
  77.         move.l    storage,a1
  78.         move    d1,trapWord(a1)
  79.         move.l    a0,parms(a1)
  80.  
  81.         and        #0xff,d1
  82.         lsl        #2,d1            /* this is also done in dispatcher, is in d2, but don't want    */
  83.         lea        oldFileTraps,a2        /* to depend on it being *4 - older ones are *2.        */
  84.         move.l    0(a2,d1.w),a2
  85.         move    trapWord(a1),d1
  86.  
  87.         bset        #10,d1
  88.         bne        @isAsync1
  89.         move.l    OFFSET(ioParam,ioCompletion)(a0),completion(a1)
  90.         clr.l        OFFSET(ioParam,ioCompletion)(a0)
  91. isAsync1:    move.l    4(sp),dispatcher(a1)        /* save dispatcher return address    */
  92.         move.l    (sp)+,a5                /* restore globals pointer            */
  93.         addq.l    #4,sp                /* clear dispatcher return address    */
  94.         jsr        (a2)                    /* call wherever, even a patch!    */
  95.         subq.l    #4,sp                /* make room for disp. addr.        */
  96.         move.l    a5,-(sp)                /* save old globals pointer        */
  97.         move.l    CurrentA5,a5            /* get our own.                */
  98.         move.l    storage,a1
  99.         move.l    dispatcher(a1),4(sp)        /* restore dispatcher return addr    */
  100.         
  101.         move.l    d1,-(sp)
  102.         move    trapWord(a1),d1
  103.         btst        #10,d1
  104.         bne        @isAsync
  105.         movem.l    d2-d7/a0-a4,-(sp)
  106.         bra        @waitSkip
  107. waitDone:    jsr        doFileBackground
  108.         move.l    storage,a1
  109. waitSkip:    move.l    parms(a1),a2
  110.         cmp        #1,OFFSET(ioParam,ioResult)(a2)
  111.         beq        @waitDone
  112.         move    OFFSET(ioParam,ioResult)(a2),d0
  113.         move.l    completion(a1),OFFSET(ioParam,ioCompletion)(a2)
  114.         movem.l    (sp)+,d2-d7/a0-a4
  115. isAsync:    sub.l        #storageCount,storage
  116.         move.l    (sp)+,d1
  117.         move.l    (sp)+,a5
  118.         rts
  119.         }
  120.     }
  121.  
  122. installFileTraps() {
  123.     int    i;
  124.  
  125.     for( i = 0; i < trapCount; ++i )
  126.         if( whichTraps[ i ] ) {
  127.             oldFileTraps[ i ] = NGetTrapAddress( i, OSTrap );
  128.             NSetTrapAddress( doFileTrap, i, OSTrap );
  129.         }
  130. }
  131.  
  132. removeFileTraps() {
  133.     int    i;
  134.     
  135.     for( i = 0; i < trapCount; ++i )
  136.         if( whichTraps[ i ] )
  137.             NSetTrapAddress( oldFileTraps[ i ], i, OSTrap );
  138. }
  139.  
  140. fixup() {
  141.     int    fake;    
  142.  
  143.     removeFileTraps();
  144.     DebugStr( "\pFile Traps Removed." );
  145. }
  146.